package by.pavlyukevich.paymentsystem.page;

import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.event.Broadcast;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.ResourceModel;

import by.pavlyukevich.paymentsystem.add.ErrorEvent;
import by.pavlyukevich.paymentsystem.add.PanelUpdateEvent;
import by.pavlyukevich.paymentsystem.add.PaymentEvent;
import by.pavlyukevich.paymentsystem.add.SelectEvent;
import by.pavlyukevich.paymentsystem.add.UpdateEvent;
import by.pavlyukevich.paymentsystem.dataaccess.filter.AccountFilter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.CardFilter;
import by.pavlyukevich.paymentsystem.dataaccess.filter.CardLimitFilter;
import by.pavlyukevich.paymentsystem.datamodel.Account;
import by.pavlyukevich.paymentsystem.datamodel.Transaction;
import by.pavlyukevich.paymentsystem.datamodel.card.Card;
import by.pavlyukevich.paymentsystem.datamodel.user.UserAccount;
import by.pavlyukevich.paymentsystem.panel.AccountListPanel;
import by.pavlyukevich.paymentsystem.panel.PaymentPanel;
import by.pavlyukevich.paymentsystem.panel.card.CardLimitListPanel;
import by.pavlyukevich.paymentsystem.panel.card.CardListPanel;
import by.pavlyukevich.paymentsystem.webapp.BasicAuthenticationSession;

import com.googlecode.wicket.jquery.ui.widget.menu.IMenuItem;
import com.googlecode.wicket.jquery.ui.widget.menu.Menu;
import com.googlecode.wicket.jquery.ui.widget.menu.MenuItem;

public class IndividualPage extends BaseLayout {

	private Card currCard;

	public IndividualPage() {

		UserAccount userAccount = BasicAuthenticationSession.get().getUserAccount();
		WebMarkupContainer currentCard = new WebMarkupContainer("currentCardDiv") {
			@Override
			public void onEvent(IEvent<?> event) {
				if (event.getPayload() instanceof SelectEvent) {
					SelectEvent selectEvent = (SelectEvent) event.getPayload();
					if (selectEvent.getObject() instanceof Card) {
						currCard = (Card) selectEvent.getObject();
						Label currCardLabel = new Label("currentCard", currCard.getCardNumber());
						replace(currCardLabel);
						selectEvent.getTarget().add(currCardLabel);
					}
				}
			}
		};
		add(currentCard);
		currentCard.add(new Label("currentCard", "").setOutputMarkupId(true));

		currentCard.add(new FeedbackPanel("feedback") {

			@Override
			public void onEvent(IEvent<?> event) {
				if (event.getPayload() instanceof ErrorEvent) {
					ErrorEvent errorEvent = (ErrorEvent) event.getPayload();
					errorEvent.getTarget().add(this);
				}
				if (event.getPayload() instanceof PanelUpdateEvent) {
					PanelUpdateEvent panelUpdateEvent = (PanelUpdateEvent) event.getPayload();
					panelUpdateEvent.getTarget().add(this);
				}
				if (event.getPayload() instanceof PaymentEvent) {
					PaymentEvent paymentEvent = (PaymentEvent) event.getPayload();
					paymentEvent.getTarget().add(this);
				}
			}
		}.setOutputMarkupId(true));

		add(new WebMarkupContainer("accountsContainer") {
			@Override
			public void onEvent(IEvent<?> event) {
				if (event.getPayload() instanceof UpdateEvent) {
					UpdateEvent blockEvent = (UpdateEvent) event.getPayload();
					if (blockEvent.getObject() instanceof Account) {
						blockEvent.getTarget().add(this);
					}
				}
			}
		}.add(new AccountListPanel("accounts", new AccountFilter().setUserAccount(userAccount)))
				.setOutputMarkupId(true));

		add(new WebMarkupContainer("cardsContainer") {
			@Override
			public void onEvent(IEvent<?> event) {
				if (event.getPayload() instanceof UpdateEvent) {
					UpdateEvent blockEvent = (UpdateEvent) event.getPayload();
					if (blockEvent.getObject() instanceof Card) {
						blockEvent.getTarget().add(this);
					}
				}
			}
		}.add(new CardListPanel("cards", new CardFilter().setAccountOwner(userAccount)))
				.setOutputMarkupId(true));

		add(new WebMarkupContainer("cardLimitsContainer") {
			@Override
			public void onEvent(IEvent<?> event) {
				if (event.getPayload() instanceof SelectEvent) {
					SelectEvent selectEvent = (SelectEvent) event.getPayload();
					if (selectEvent.getObject() instanceof Card) {
						currCard = (Card) selectEvent.getObject();
						replace(new CardLimitListPanel("ac-panel",
								new CardLimitFilter().setCard(currCard)));
						selectEvent.getTarget().add(this);
					}
				}

				if (event.getPayload() instanceof PanelUpdateEvent) {
					PanelUpdateEvent pUpdateEvent = (PanelUpdateEvent) event.getPayload();
					addOrReplace(pUpdateEvent.getPanel());
					add(new AttributeModifier("style", ""));
					pUpdateEvent.getTarget().add(this);
				}
			}
		}.add(new CardLimitListPanel("ac-panel", new CardLimitFilter().setCard(currCard)))
				.add(new AttributeModifier("style", "display:none")).setOutputMarkupId(true));

		add(new Menu("paymentMenu", paymentMenu()));

		add(new WebMarkupContainer("paymentContainer") {

			@Override
			public void onEvent(IEvent<?> event) {
				if (event.getPayload() instanceof PaymentEvent) {
					PaymentEvent paymentEvent = (PaymentEvent) event.getPayload();
					add(new AttributeModifier("style", ""));

					Transaction transaction = new Transaction();
					transaction.setSenderCard(currCard);

					replace(new PaymentPanel("payment", transaction));
					paymentEvent.getTarget().add(this);
				}
				if (event.getPayload() instanceof UpdateEvent) {
					add(new AttributeModifier("style", "display:none"));
					UpdateEvent updateEvent = (UpdateEvent) event.getPayload();
					updateEvent.getTarget().add(this);
				}

			}
		}.add(new WebMarkupContainer("payment"))
				.add(new AttributeModifier("style", "display:none")).setOutputMarkupId(true));

	}

	public List<IMenuItem> paymentMenu() {
		List<IMenuItem> itemList = new ArrayList<IMenuItem>();

		itemList.add(new MenuItem(new ResourceModel("l.arbitPayment.title")) {
			@Override
			public void onClick(AjaxRequestTarget target) {

				if (currCard == null) {
					error(new ResourceModel("t.error.card").getObject());
					send(getPage(), Broadcast.BREADTH, new ErrorEvent(target));
					return;
				}
				;
				Transaction transaction = new Transaction();
				transaction.setSenderCard(currCard);
				send(getPage(), Broadcast.BREADTH, new PaymentEvent(target, transaction));
			}
		});

		return itemList;
	}
}
